package com.scx.utils;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;

public class JdbcUtil {
	static Logger log = Logger.getLogger(JdbcUtil.class);
	private final static String MYSQL_URL = "jdbc:mysql://139.198.190.182:3306/qiaohaoba?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false";
	// 账号
	private final static String MYSQL_USERNAME = "qhbadmin";
	// 密码
	private final static String MYSQL_PASSWORD = "zQ556677";
	private final static String MYSQL_DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
	// 地址
	// 初始化时建立物理连接的个数
	private final static int MYSQL_INITIAL_SIZE = 50;
	// 同一时间可以从池分配的最多连接数量。设置为0时表示无限制
	private final static int MYSQL_MAX_ACTIVE = 400;
	// 最大等待时长
	private final static long MYSQL_MAX_WAIT = 3550;
	// 连接保持空闲而不被驱逐的最长时间
	private final static long MYSQL_MIN_EVICTABLE_IDLE_TIME_MILLIS = 3550;
	// 检测连接是否有效的sql
	private final static String MYSQL_VALIDATION_QUERY= "select 1";
	// 执行validationQuery检测连接是否有效
	private final static boolean MYSQL_TEST_WHILE_IDLE = true;
	// 申请连接时执行validationQuery检测连接是否有效
	private final static boolean MYSQL_TEST_ON_BORROW = false;
	// 归还连接时执行validationQuery检测连接是否有效
	private final static boolean MYSQL_TEST_ON_RETURN = false;
	// 是否缓存preparedStatement，也就是PSCache
	private final static boolean MYSQL_POOL_PREPARED_STATEMENTS = true;
	private final static int MYSQL_MAX_POOL_PREPARED_STATEMENT_PER_CONNECTION_SIZE = 30;
	// 超时回收链接
	private final static boolean MYSQL_REMOVE_ABANDONED = true;
	private final static int MYSQL_REMOVE_ABANDONED_TIMEOUT = 9000;
	
	
	private static JdbcUtil dbPoolConnection = null;
	private static DruidDataSource druidDataSource = null;
	static {
		try {
			druidDataSource = new DruidDataSource();
			// 设置用户名
			druidDataSource.setUsername(MYSQL_USERNAME);
			// 设置密码
			druidDataSource.setPassword(MYSQL_PASSWORD);
			// 设置链接地址
			druidDataSource.setUrl(MYSQL_URL);
			// 初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时
			druidDataSource.setInitialSize(MYSQL_INITIAL_SIZE);
			// 最大连接池数量
			druidDataSource.setMaxActive(MYSQL_MAX_ACTIVE);
			// 获取连接时最大等待时间，单位毫秒。配置了maxWait之后， 缺省启用公平锁，并发效率会有所下降， 如果需要可以通过配置useUnfairLock属性为true使用非公平锁
			druidDataSource.setMaxWait(MYSQL_MAX_WAIT);
			druidDataSource.setMinEvictableIdleTimeMillis(MYSQL_MIN_EVICTABLE_IDLE_TIME_MILLIS);
			// getValue("")
			// 用来检测连接是否有效的sql，要求是一个查询语句。 如果validationQuery为null，testOnBorrow、testOnReturn、 testWhileIdle都不会其作用。
			druidDataSource.setValidationQuery(MYSQL_VALIDATION_QUERY);
			// 建议配置为true，不影响性能，并且保证安全性。 申请连接的时候检测，如果空闲时间大于 timeBetweenEvictionRunsMillis， 执行validationQuery检测连接是否有效。
			druidDataSource.setTestWhileIdle(MYSQL_TEST_WHILE_IDLE);
			// 申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。
			druidDataSource.setTestOnBorrow(MYSQL_TEST_ON_BORROW);
			// 归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能
			druidDataSource.setTestOnReturn(MYSQL_TEST_ON_RETURN);
			//是否缓存preparedStatement，也就是PSCache。 PSCache对支持游标的数据库性能提升巨大，比如说oracle。 在mysql5.5以下的版本中没有PSCache功能，建议关闭掉。
			druidDataSource.setPoolPreparedStatements(MYSQL_POOL_PREPARED_STATEMENTS);
			druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(MYSQL_MAX_POOL_PREPARED_STATEMENT_PER_CONNECTION_SIZE);
			druidDataSource.setDriverClassName(MYSQL_DRIVER_CLASS_NAME);
			// 超时回收链接
			druidDataSource.setRemoveAbandoned(MYSQL_REMOVE_ABANDONED);
			druidDataSource.setRemoveAbandonedTimeout(MYSQL_REMOVE_ABANDONED_TIMEOUT);
			druidDataSource.setMinEvictableIdleTimeMillis(MYSQL_MIN_EVICTABLE_IDLE_TIME_MILLIS);
		} catch (Exception e) {
			log.error("获取配置失败");
		}
	}
	
	/**
	 * 
	 * 数据库连接池单例。
	 * <p></p>
	 * @return JdbcUtil对象
	 */
	public static synchronized JdbcUtil getInstance(){
		if (null == dbPoolConnection){
			dbPoolConnection = new JdbcUtil();
		}
		return dbPoolConnection;
	}
	
	/**
	 * 
	 * 获得druid数据库连接。
	 * <p></p>
	 * @return 链接对象
	 * @throws SQLException
	 */
	public DruidPooledConnection getConnection() throws SQLException{
		return druidDataSource.getConnection();
	}
}
